<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ChannelCode\Action\Workbench;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Common\Middleware\WorkbenchAuthMiddleware;
use MoChat\App\WorkContact\Contract\WorkContactTagContract;
use MoChat\App\WorkContact\Contract\WorkContactTagGroupContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\ChannelCode\Contract\ChannelCodeContract;
use MoChat\Plugin\ChannelCode\Contract\ChannelCodeGroupContract;
use MoChat\Plugin\Greeting\Action\Dashboard\Traits\MediumTrait;

/**
 * 渠道码详情.
 *
 * Class Show
 * @Controller
 */
class Show extends AbstractAction
{
    use ValidateSceneTrait;
    use MediumTrait;

    /**
     * 标签分组表.
     * @Inject
     * @var WorkContactTagGroupContract
     */
    protected $workContactTagGroupService;

    /**
     * 标签表.
     * @Inject
     * @var WorkContactTagContract
     */
    protected $workContactTagService;

    /**
     * @Inject
     * @var ChannelCodeContract
     */
    protected $channelCodeService;

    /**
     * @Inject
     * @var ChannelCodeGroupContract
     */
    protected $channelCodeGroupService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Middlewares({
     *     @Middleware(WorkbenchAuthMiddleware::class)
     * })
     * @RequestMapping(path="/workbench/channelCode/show", methods="GET")
     */
    public function handle()
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpId'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $params['userId'] = (int) $user['logUserId'];
        $params['corpId'] = $user['corpId'];
        $params['employeeId'] = $user['id'];

        // 接收参数
        $params['channelCodeId'] = $this->request->input('channelCodeId');

        // 验证参数
        $this->validated($params);

        $info = $this->channelCodeService->getChannelCodeById((int) $params['channelCodeId']);
        if (empty($info)) {
            return [];
        }
        $workContactTagList = $this->getWorkContactTagList(Json::decode($info['tags'], true), $params['corpId']);
        // 基础信息
        $baseInfo = [
            'groupId' => $info['groupId'],
            'groupName' => ! empty($this->getGroup($info['groupId'])) ? $this->getGroup($info['groupId'])['name'] : '未分组',
            'name' => $info['name'],
            'autoAddFriend' => $info['autoAddFriend'],
            'tags' => Json::decode($info['tags'], true),
            'fullTags' => $this->getTags(Json::decode($info['tags'], true)),
            'corpTags' => $workContactTagList['tagGroupAllList'] ?? [],
            'contactRemark' => Json::decode($info['contactRemark']),
            'contactDescription' => $info['contactDescription'],
            'image' => empty($info['image']) ? '' : file_full_url($info['image']),
        ];

        return [
            'type' => $info['type'],
            'baseInfo' => $baseInfo,
            'drainageEmployee' => $this->getDrainageEmployee(Json::decode($info['drainageEmployee'])),
            'welcomeMessage' => $this->handleWelcome($info),
            'spanWelcomeStatus' => $info['spanWelcomeStatus'],
            'spanWelcome' => $this->handleSpanWelcome($info),
            'closeWords' => ! empty($info['closeWords']) ? Json::decode($info['closeWords']) : [],
        ];
    }

    /**
     * @return string[] 规则
     */
    public function rules(): array
    {
        return [
            'channelCodeId' => 'required',
        ];
    }

    /**
     * 获取已定义验证规则的错误消息.
     */
    public function messages(): array
    {
        return [
            'channelCodeId.required' => '渠道码id必传',
        ];
    }

    private function getDrainageEmployee($drainageEmployee): array
    {
        if ($drainageEmployee['type'] === 1) {
            $drainageEmployee['timeFull'] = $this->getEmployees(array_column($drainageEmployee['timeFull'], 'id'));
        }
        if ($drainageEmployee['type'] === 2) {
            foreach ($drainageEmployee['timeSlot'] as &$item) {
                $item['employees'] = $this->getEmployees(array_column($item['employees'], 'id'));
            }
        }
        unset($item);
        if (! empty($drainageEmployee['specialPeriod'])) {
            $drainageEmployee['specialPeriod'] = $this->getEmployees(array_column($drainageEmployee['specialPeriod'], 'id'));
        }
        if (! empty($drainageEmployee['addMax']) && $drainageEmployee['addMax']['status'] === 1) {
            $employees = $this->getEmployees(array_column($drainageEmployee['addMax']['employees'], 'id'));
            $employees = array_column($employees, null, 'id');
            foreach ($drainageEmployee['addMax']['employees'] as &$val) {
                $val['avatar'] = ! empty($employees[$val['id']]) ? $employees[$val['id']]['avatar'] : '';
            }
            unset($val);
        }
        return $drainageEmployee;
    }

    private function getEmployees($employeeIds): array
    {
        $employees = $this->workEmployeeService->getWorkEmployeesById($employeeIds, ['id', 'name', 'avatar']);
        foreach ($employees as &$item) {
            $item['avatar'] = file_full_url($item['avatar']);
        }
        return $employees;
    }

    private function getTags($tagIds): array
    {
        return $this->workContactTagService->getWorkContactTagsById($tagIds, ['id', 'name']);
    }

    /**
     * 处理欢迎语设置.
     * @param $info
     * @return mixed
     */
    private function handleSpanWelcome($info)
    {
        $spanWelcome = Json::decode($info['spanWelcome'], true);
        foreach ($spanWelcome as &$value) {
            $value['content'] = [];
            if (! empty($value['mediumId'])) {
                $value['content'] = $this->handleMedium($value['mediumId']);
            }
        }
        unset($value);

        return $spanWelcome;
    }

    /**
     * 处理欢迎语设置.
     * @param $info
     * @return mixed
     */
    private function handleWelcome($info)
    {
        $spanWelcome = Json::decode($info['welcomeMessage'], true);
        $spanWelcome['content'] = [];
        if (! empty($spanWelcome['mediumId'])) {
            $spanWelcome['content'] = $this->handleMedium($spanWelcome['mediumId']);
        }

        return $spanWelcome;
    }

    /**
     * 获取渠道码分组信息.
     * @param $groupId
     * @return array
     */
    private function getGroup($groupId)
    {
        $res = $this->channelCodeGroupService->getChannelCodeGroupById((int) $groupId, ['name']);
        if (empty($res)) {
            return [];
        }

        return $res;
    }

    /**
     * @param array $workContactTagIds 客户标签ID数组
     * @param int $corpId 企业授信ID
     * @return array 响应数组
     */
    private function getWorkContactTagList(array $workContactTagIds, int $corpId): array
    {
        // 当前企业全部客户标签
        $tagList = $this->workContactTagService->getWorkContactTagsByCorpId([$corpId], ['id', 'name', 'contact_tag_group_id']);
        if (empty($tagList)) {
            return [];
        }
        // 客户标签分组
        $contactTagGroupIds = array_filter(array_unique(array_column($tagList, 'contactTagGroupId')));
        $tagGroupList = $this->workContactTagGroupService->getWorkContactTagGroupsById($contactTagGroupIds, ['id', 'group_name']);
        $tagGroupAllList = [
        ];
        if (! empty($tagGroupList)) {
            foreach ($tagGroupList as $tagGroup) {
                $tagGroupAllList[$tagGroup['id']] = [
                    'groupId' => $tagGroup['id'],
                    'groupName' => $tagGroup['groupName'],
                    'list' => [],
                ];
            }
        }
        // 标签分类处理
        $selectedTags = [];
        foreach ($tagList as $tag) {
            if (! isset($tagGroupAllList[$tag['contactTagGroupId']])) {
                continue;
            }
            in_array($tag['id'], $workContactTagIds, true) && $selectedTags[] = $tag['id'];
            $tagGroupAllList[$tag['contactTagGroupId']]['list'][] = [
                'tagId' => $tag['id'],
                'tagName' => $tag['name'],
                'isSelected' => in_array($tag['id'], $workContactTagIds, true) ? 1 : 2,
            ];
        }
        return [
            'tagGroupAllList' => array_values($tagGroupAllList),
            'selectedTags' => $selectedTags,
        ];
    }
}
